home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / text / edit / vim60src.lha / Vim / vim60 / src / charset.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-19  |  35.5 KB  |  1,630 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. #include "vim.h"
  11.  
  12. #ifdef FEAT_LINEBREAK
  13. static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col));
  14. #endif
  15.  
  16. #ifdef FEAT_MBYTE
  17. static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
  18. #endif
  19.  
  20. static int nr2hex __ARGS((int c));
  21.  
  22. static int    chartab_initialized = FALSE;
  23.  
  24. /* b_chartab[] is an array of 32 bytes, each bit representing one of the
  25.  * characters 0-255. */
  26. #define SET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7))
  27. #define RESET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7))
  28. #define GET_CHARTAB(buf, c) ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
  29.  
  30. /*
  31.  * Fill chartab[].  Also fills curbuf->b_chartab[] with flags for keyword
  32.  * characters for current buffer.
  33.  *
  34.  * Depends on the option settings 'iskeyword', 'isident', 'isfname',
  35.  * 'isprint' and 'encoding'.
  36.  *
  37.  * The index in chartab[] depends on 'encoding':
  38.  * - For non-multi-byte index with the byte (same as the character).
  39.  * - For DBCS index with the first byte.
  40.  * - For UTF-8 index with the character (when first byte is up to 0x80 it is
  41.  *   the same as the character, if the first byte is 0x80 and above it depends
  42.  *   on further bytes).
  43.  *
  44.  * The contents of chartab[]:
  45.  * - The lower two bits, masked by CT_CELL_MASK, give the number of display
  46.  *   cells the character occupies (1 or 2).  Not valid for UTF-8 above 0x80.
  47.  * - CT_PRINT_CHAR bit is set when the character is printable (no need to
  48.  *   translate the character before displaying it).  Note that only DBCS
  49.  *   characters can have 2 display cells and still be printable.
  50.  * - CT_FNAME_CHAR bit is set when the character can be in a file name.
  51.  * - CT_ID_CHAR bit is set when the character can be in an identifier.
  52.  *
  53.  * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
  54.  * error, OK otherwise.
  55.  */
  56.     int
  57. init_chartab()
  58. {
  59.     return buf_init_chartab(curbuf, TRUE);
  60. }
  61.  
  62.     int
  63. buf_init_chartab(buf, global)
  64.     buf_T    *buf;
  65.     int        global;        /* FALSE: only set buf->b_chartab[] */
  66. {
  67.     int        c;
  68.     int        c2;
  69.     char_u    *p;
  70.     int        i;
  71.     int        tilde;
  72.     int        do_isalpha;
  73.  
  74.     if (global)
  75.     {
  76.     /*
  77.      * Set the default size for printable characters:
  78.      * From <Space> to '~' is 1 (printable), others are 2 (not printable).
  79.      * This also inits all 'isident' and 'isfname' flags to FALSE.
  80.      *
  81.      * EBCDIC: all chars below ' ' are not printable, all others are
  82.      * printable.
  83.      */
  84.     c = 0;
  85.     while (c < ' ')
  86.         chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
  87. #ifdef EBCDIC
  88.     while (c < 255)
  89. #else
  90.     while (c <= '~')
  91. #endif
  92.         chartab[c++] = 1 + CT_PRINT_CHAR;
  93. #ifdef FEAT_FKMAP
  94.     if (p_altkeymap)
  95.     {
  96.         while (c < YE)
  97.         chartab[c++] = 1 + CT_PRINT_CHAR;
  98.     }
  99. #endif
  100.     while (c < 256)
  101.     {
  102. #ifdef FEAT_MBYTE
  103.         /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
  104.         if (enc_utf8 && c >= 0xa0)
  105.         chartab[c++] = CT_PRINT_CHAR + 1;
  106.         /* euc-jp characters starting with 0x8e are single width */
  107.         else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
  108.         chartab[c++] = CT_PRINT_CHAR + 1;
  109.         /* other double-byte chars can be printable AND double-width */
  110.         else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
  111.         chartab[c++] = CT_PRINT_CHAR + 2;
  112.         else
  113. #endif
  114.         /* the rest is unprintable by default */
  115.         chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
  116.     }
  117.  
  118. #ifdef FEAT_MBYTE
  119.     /* Assume that every multi-byte char is a filename character. */
  120.     for (c = 1; c < 256; ++c)
  121.         if ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1)
  122.             || (enc_dbcs == DBCS_JPNU && c == 0x8e)
  123.             || (enc_utf8 && c >= 0xa0))
  124.         chartab[c] |= CT_FNAME_CHAR;
  125. #endif
  126.     }
  127.  
  128.     /*
  129.      * Init word char flags all to FALSE
  130.      */
  131.     vim_memset(buf->b_chartab, 0, (size_t)32);
  132. #ifdef FEAT_MBYTE
  133.     for (c = 0; c < 256; ++c)
  134.     {
  135.     /* double-byte characters are probably word characters */
  136.     if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
  137.         SET_CHARTAB(buf, c);
  138.     }
  139. #endif
  140.  
  141. #ifdef FEAT_LISP
  142.     /*
  143.      * In lisp mode the '-' character is included in keywords.
  144.      */
  145.     if (buf->b_p_lisp)
  146.     SET_CHARTAB(buf, '-');
  147. #endif
  148.  
  149.     /* Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
  150.      * options Each option is a list of characters, character numbers or
  151.      * ranges, separated by commas, e.g.: "200-210,x,#-178,-"
  152.      */
  153.     for (i = global ? 0 : 3; i <= 3; ++i)
  154.     {
  155.     if (i == 0)
  156.         p = p_isi;        /* first round: 'isident' */
  157.     else if (i == 1)
  158.         p = p_isp;        /* second round: 'isprint' */
  159.     else if (i == 2)
  160.         p = p_isf;        /* third round: 'isfname' */
  161.     else    /* i == 3 */
  162.         p = buf->b_p_isk;    /* fourth round: 'iskeyword' */
  163.  
  164.     while (*p)
  165.     {
  166.         tilde = FALSE;
  167.         do_isalpha = FALSE;
  168.         if (*p == '^' && p[1] != NUL)
  169.         {
  170.         tilde = TRUE;
  171.         ++p;
  172.         }
  173.         if (isdigit(*p))
  174.         c = getdigits(&p);
  175.         else
  176.         c = *p++;
  177.         c2 = -1;
  178.         if (*p == '-' && p[1] != NUL)
  179.         {
  180.         ++p;
  181.         if (isdigit(*p))
  182.             c2 = getdigits(&p);
  183.         else
  184.             c2 = *p++;
  185.         }
  186.         if (c <= 0 || (c2 < c && c2 != -1) || c2 >= 256
  187.                          || !(*p == NUL || *p == ','))
  188.         return FAIL;
  189.  
  190.         if (c2 == -1)    /* not a range */
  191.         {
  192.         /*
  193.          * A single '@' (not "@-@"):
  194.          * Decide on letters being ID/printable/keyword chars with
  195.          * standard function isalpha(). This takes care of locale for
  196.          * single-byte characters).
  197.          */
  198.         if (c == '@')
  199.         {
  200.             do_isalpha = TRUE;
  201.             c = 1;
  202.             c2 = 255;
  203.         }
  204.         else
  205.             c2 = c;
  206.         }
  207.         while (c <= c2)
  208.         {
  209.         if (!do_isalpha || isalpha(c)
  210. #ifdef FEAT_FKMAP
  211.             || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
  212. #endif
  213.                 )
  214.         {
  215.             if (i == 0)            /* (re)set ID flag */
  216.             {
  217.             if (tilde)
  218.                 chartab[c] &= ~CT_ID_CHAR;
  219.             else
  220.                 chartab[c] |= CT_ID_CHAR;
  221.             }
  222.             else if (i == 1)        /* (re)set printable */
  223.             {
  224.             if ((c < ' '
  225. #ifndef EBCDIC
  226.                     || c > '~'
  227. #endif
  228. #ifdef FEAT_FKMAP
  229.                     || (p_altkeymap
  230.                     && (F_isalpha(c) || F_isdigit(c)))
  231. #endif
  232.                 )
  233. #ifdef FEAT_MBYTE
  234.                 /* For double-byte we keep the cell width, so
  235.                  * that we can detect it from the first byte. */
  236.                 && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
  237. #endif
  238.                )
  239.             {
  240.                 if (tilde)
  241.                 {
  242.                 chartab[c] = (chartab[c] & ~CT_CELL_MASK)
  243.                          + ((dy_flags & DY_UHEX) ? 4 : 2);
  244.                 chartab[c] &= ~CT_PRINT_CHAR;
  245.                 }
  246.                 else
  247.                 {
  248.                 chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
  249.                 chartab[c] |= CT_PRINT_CHAR;
  250.                 }
  251.             }
  252.             }
  253.             else if (i == 2)        /* (re)set fname flag */
  254.             {
  255.             if (tilde)
  256.                 chartab[c] &= ~CT_FNAME_CHAR;
  257.             else
  258.                 chartab[c] |= CT_FNAME_CHAR;
  259.             }
  260.             else /* i == 3 */        /* (re)set keyword flag */
  261.             {
  262.             if (tilde)
  263.                 RESET_CHARTAB(buf, c);
  264.             else
  265.                 SET_CHARTAB(buf, c);
  266.             }
  267.         }
  268.         ++c;
  269.         }
  270.         p = skip_to_option_part(p);
  271.     }
  272.     }
  273.     chartab_initialized = TRUE;
  274.     return OK;
  275. }
  276.  
  277. #if defined(FEAT_STL_OPT) || defined(FEAT_WINDOWS) || defined(PROTO)
  278. /*
  279.  * Translate any special characters in buf[bufsize] in-place.
  280.  * If there is not enough room, not all characters will be translated.
  281.  */
  282.     void
  283. trans_characters(buf, bufsize)
  284.     char_u    *buf;
  285.     int        bufsize;
  286. {
  287.     int        len;        /* length of string needing translation */
  288.     int        room;        /* room in buffer after string */
  289.     char_u    *trs;        /* translated character */
  290.     int        trs_len;    /* length of trs[] */
  291.  
  292.     len = (int)STRLEN(buf);
  293.     room = bufsize - len;
  294.     while (*buf != 0)
  295.     {
  296. #ifdef FEAT_MBYTE
  297.     /* Assume a multi-byte character doesn't need translation. */
  298.     if (has_mbyte && (trs_len = (*mb_ptr2len_check)(buf)) > 1)
  299.         len -= trs_len;
  300.     else
  301. #endif
  302.     {
  303.         trs = transchar(*buf);
  304.         trs_len = (int)STRLEN(trs);
  305.         if (trs_len > 1)
  306.         {
  307.         room -= trs_len - 1;
  308.         if (room <= 0)
  309.             return;
  310.         mch_memmove(buf + trs_len, buf + 1, (size_t)len);
  311.         }
  312.         mch_memmove(buf, trs, (size_t)trs_len);
  313.         --len;
  314.     }
  315.     buf += trs_len;
  316.     }
  317. }
  318. #endif
  319.  
  320. #if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(PROTO)
  321. /*
  322.  * Translate a string into allocated memory, replacing special chars with
  323.  * printable chars.  Returns NULL when out of memory.
  324.  */
  325.     char_u *
  326. transstr(s)
  327.     char_u    *s;
  328. {
  329.     char_u    *res;
  330. #ifdef FEAT_MBYTE
  331.     int        l;
  332. #endif
  333.  
  334.     res = alloc((unsigned)(vim_strsize(s) + 1));
  335.     if (res != NULL)
  336.     {
  337.     *res = NUL;
  338.     while (*s != NUL)
  339.     {
  340. #ifdef FEAT_MBYTE
  341.         if (has_mbyte && (l = (*mb_ptr2len_check)(s)) > 1)
  342.         {
  343.         STRNCAT(res, s, l);
  344.         s += l;
  345.         }
  346.         else
  347. #endif
  348.         STRCAT(res, transchar(*s++));
  349.     }
  350.     }
  351.     return res;
  352. }
  353. #endif
  354.  
  355. #if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO)
  356. /*
  357.  * Convert the string "p" to do ignore-case comparing.
  358.  * It's done in-place.
  359.  */
  360.     void
  361. str_foldcase(p)
  362.     char_u    *p;
  363. {
  364.     while (*p != NUL)
  365.     {
  366. #ifdef FEAT_MBYTE
  367.     if (has_mbyte && MB_BYTE2LEN(*p) > 1)
  368.     {
  369.         if (enc_utf8)
  370.         {
  371.         int    c, lc;
  372.  
  373.         c = utf_ptr2char(p);
  374.         lc = utf_tolower(c);
  375.         if (c != lc && utf_char2len(c) == utf_char2len(lc))
  376.             (void)utf_char2bytes(c, p);
  377.         }
  378.         p += (*mb_ptr2len_check)(p);    /* skip multi-byte char */
  379.     }
  380.     else
  381. #endif
  382.     {
  383.         *p = TO_LOWER(*p);
  384.         ++p;
  385.     }
  386.     }
  387. }
  388. #endif
  389.  
  390. /*
  391.  * Catch 22: chartab[] can't be initialized before the options are
  392.  * initialized, and initializing options may cause transchar() to be called!
  393.  * When chartab_initialized == FALSE don't use chartab[].
  394.  * Does NOT work for multi-byte characters, c must be <= 255.
  395.  */
  396.     char_u *
  397. transchar(c)
  398.     int        c;
  399. {
  400.     static char_u    buf[7];
  401.     int            i;
  402.  
  403.     i = 0;
  404.     if (IS_SPECIAL(c))        /* special key code, display as ~@ char */
  405.     {
  406.     buf[0] = '~';
  407.     buf[1] = '@';
  408.     i = 2;
  409.     c = K_SECOND(c);
  410.     }
  411.  
  412.     if ((!chartab_initialized && (
  413. #ifdef EBCDIC
  414.             (c >= 64 && c < 255)
  415. #else
  416.             (c >= ' ' && c <= '~')
  417. #endif
  418. #ifdef FEAT_FKMAP
  419.             || F_ischar(c)
  420. #endif
  421.         )) || (c < 256 && vim_isprintc_strict(c)))
  422.     {
  423.     /* printable character */
  424.     buf[i] = c;
  425.     buf[i + 1] = NUL;
  426.     }
  427.     else
  428.     transchar_nonprint(buf + i, c);
  429.     return buf;
  430. }
  431.  
  432. /*
  433.  * Convert non-printable character to two or more printable characters in
  434.  * "buf[]".  "buf" needs to be able to hold five bytes.
  435.  * Does NOT work for multi-byte characters, c must be <= 255.
  436.  */
  437.     void
  438. transchar_nonprint(buf, c)
  439.     char_u    *buf;
  440.     int        c;
  441. {
  442.     if (c == NL)
  443.     c = NUL;        /* we use newline in place of a NUL */
  444.     else if (c == CR && get_fileformat(curbuf) == EOL_MAC)
  445.     c = NL;            /* we use CR in place of  NL in this case */
  446.  
  447.     if (dy_flags & DY_UHEX)        /* 'display' has "uhex" */
  448.     transchar_hex(buf, c);
  449.  
  450. #ifdef EBCDIC
  451.     /* For EBCDIC only the characters 0-63 and 255 are not printable */
  452.     else if (CtrlChar(c) != 0 || c == DEL)
  453. #else
  454.     else if (c <= 0x7f)                /* 0x00 - 0x1f and 0x7f */
  455. #endif
  456.     {
  457.     buf[0] = '^';
  458. #ifdef EBCDIC
  459.     if (c == DEL)
  460.         buf[1] = '?';        /* DEL displayed as ^? */
  461.     else
  462.         buf[1] = CtrlChar(c);
  463. #else
  464.     buf[1] = c ^ 0x40;        /* DEL displayed as ^? */
  465. #endif
  466.  
  467.     buf[2] = NUL;
  468.     }
  469. #ifdef FEAT_MBYTE
  470.     else if (enc_utf8 && c >= 0x80)
  471.     {
  472.     transchar_hex(buf, c);
  473.     }
  474. #endif
  475. #ifndef EBCDIC
  476.     else if (c >= ' ' + 0x80 && c <= '~' + 0x80)    /* 0xa0 - 0xfe */
  477.     {
  478.     buf[0] = '|';
  479.     buf[1] = c - 0x80;
  480.     buf[2] = NUL;
  481.     }
  482. #else
  483.     else if (c < 64)
  484.     {
  485.     buf[0] = '~';
  486.     buf[1] = MetaChar(c);
  487.     buf[2] = NUL;
  488.     }
  489. #endif
  490.     else                        /* 0x80 - 0x9f and 0xff */
  491.     {
  492.     /*
  493.      * TODO: EBCDIC I don't know what to do with this chars, so I display
  494.      * them as '~?' for now
  495.      */
  496.     buf[0] = '~';
  497. #ifdef EBCDIC
  498.     buf[1] = '?';            /* 0xff displayed as ~? */
  499. #else
  500.     buf[1] = (c - 0x80) ^ 0x40;    /* 0xff displayed as ~? */
  501. #endif
  502.     buf[2] = NUL;
  503.     }
  504. }
  505.  
  506.     void
  507. transchar_hex(buf, c)
  508.     char_u    *buf;
  509.     int        c;
  510. {
  511.     int        i = 0;
  512.  
  513.     buf[0] = '<';
  514. #ifdef FEAT_MBYTE
  515.     if (c > 255)
  516.     {
  517.     buf[++i] = nr2hex((unsigned)c >> 12);
  518.     buf[++i] = nr2hex((unsigned)c >> 8);
  519.     }
  520. #endif
  521.     buf[++i] = nr2hex((unsigned)c >> 4);
  522.     buf[++i] = nr2hex(c);
  523.     buf[++i] = '>';
  524.     buf[++i] = NUL;
  525. }
  526.  
  527. /*
  528.  * Convert the lower 4 bits of byte "c" to its hex character.
  529.  * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
  530.  * function key 1.
  531.  */
  532.     static int
  533. nr2hex(c)
  534.     int        c;
  535. {
  536.     if ((c & 0xf) <= 9)
  537.     return (c & 0xf) + '0';
  538.     return (c & 0xf) - 10 + 'a';
  539. }
  540.  
  541. /*
  542.  * Return number of display cells occupied by byte "b".
  543.  * Caller must make sure 0 <= b <= 255.
  544.  * For multi-byte mode "b" must be the first byte of a character.
  545.  * A TAB is counted as two cells: "^I".
  546.  * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
  547.  * cells depends on further bytes.
  548.  */
  549.     int
  550. byte2cells(b)
  551.     int        b;
  552. {
  553. #ifdef FEAT_MBYTE
  554.     if (enc_utf8 && b >= 0x80)
  555.     return 0;
  556. #endif
  557.     return (chartab[b] & CT_CELL_MASK);
  558. }
  559.  
  560. /*
  561.  * Return number of display cells occupied by character "c".
  562.  * "c" can be a special key (negative number) in which case 3 or 4 is returned.
  563.  * A TAB is counted as two cells: "^I" or four: "<09>".
  564.  */
  565.     int
  566. char2cells(c)
  567.     int        c;
  568. {
  569.     if (IS_SPECIAL(c))
  570.     return char2cells(K_SECOND(c)) + 2;
  571. #ifdef FEAT_MBYTE
  572.     if (c >= 0x80)
  573.     {
  574.     /* UTF-8: above 0x80 need to check the value */
  575.     if (enc_utf8)
  576.         return utf_char2cells(c);
  577.     /* DBCS: double-byte means double-width, except for euc-jp with first
  578.      * byte 0x8e */
  579.     if (enc_dbcs != 0 && c >= 0x100)
  580.     {
  581.         if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
  582.         return 1;
  583.         return 2;
  584.     }
  585.     }
  586. #endif
  587.     return (chartab[c & 0xff] & CT_CELL_MASK);
  588. }
  589.  
  590. /*
  591.  * Return number of display cells occupied by character at "*p".
  592.  * A TAB is counted as two cells: "^I" or four: "<09>".
  593.  */
  594.     int
  595. ptr2cells(p)
  596.     char_u    *p;
  597. {
  598. #ifdef FEAT_MBYTE
  599.     /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
  600.     if (enc_utf8 && *p >= 0x80)
  601.     return utf_ptr2cells(p);
  602.     /* For DBCS we can tell the cell count from the first byte. */
  603. #endif
  604.     return (chartab[*p] & CT_CELL_MASK);
  605. }
  606.  
  607. /*
  608.  * Return the number of characters string 's' will take on the screen,
  609.  * counting TABs as two characters: "^I".
  610.  */
  611.     int
  612. vim_strsize(s)
  613.     char_u    *s;
  614. {
  615.     int        len = 0;
  616.  
  617.     while (*s != NUL)
  618.     {
  619. #ifdef FEAT_MBYTE
  620.     if (has_mbyte)
  621.     {
  622.         len += ptr2cells(s);
  623.         s += (*mb_ptr2len_check)(s);
  624.     }
  625.     else
  626. #endif
  627.         len += byte2cells(*s++);
  628.     }
  629.     return len;
  630. }
  631.  
  632. /*
  633.  * Return the number of characters 'c' will take on the screen, taking
  634.  * into account the size of a tab.
  635.  * Use a define to make it fast, this is used very often!!!
  636.  * Also see getvcol() below.
  637.  */
  638.  
  639. #define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
  640.     if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
  641.     { \
  642.     int ts; \
  643.     ts = (buf)->b_p_ts; \
  644.     return (int)(ts - (col % ts)); \
  645.     } \
  646.     else \
  647.     return ptr2cells(p);
  648.  
  649. #if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
  650.     || defined(FEAT_VIRTUALEDIT) || defined(PROTO)
  651.     int
  652. chartabsize(p, col)
  653.     char_u    *p;
  654.     colnr_T    col;
  655. {
  656.     RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
  657. }
  658. #endif
  659.  
  660. #ifdef FEAT_LINEBREAK
  661.     static int
  662. win_chartabsize(wp, p, col)
  663.     win_T    *wp;
  664.     char_u    *p;
  665.     colnr_T    col;
  666. {
  667.     RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
  668. }
  669. #endif
  670.  
  671. /*
  672.  * return the number of characters the string 's' will take on the screen,
  673.  * taking into account the size of a tab
  674.  */
  675.     int
  676. linetabsize(s)
  677.     char_u    *s;
  678. {
  679.     colnr_T    col = 0;
  680.  
  681.     while (*s != NUL)
  682.     col += lbr_chartabsize_adv(&s, col);
  683.     return (int)col;
  684. }
  685.  
  686. /*
  687.  * Like linetabsize(), but for a given window instead of the current one.
  688.  */
  689.     int
  690. win_linetabsize(wp, p, len)
  691.     win_T    *wp;
  692.     char_u    *p;
  693.     colnr_T    len;
  694. {
  695.     colnr_T    col = 0;
  696.     char_u    *s;
  697.  
  698.     for (s = p; *s != NUL && s < p + len; )
  699.     {
  700.     col += win_lbr_chartabsize(wp, s, col, NULL);
  701. #ifdef FEAT_MBYTE
  702.     if (has_mbyte)
  703.         s += (*mb_ptr2len_check)(s);
  704.     else
  705. #endif
  706.         ++s;
  707.     }
  708.     return (int)col;
  709. }
  710.  
  711. /*
  712.  * return TRUE if 'c' is a normal identifier character
  713.  * letters and characters from 'isident' option.
  714.  */
  715.     int
  716. vim_isIDc(c)
  717.     int c;
  718. {
  719.     return (c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR));
  720. }
  721.  
  722. /*
  723.  * return TRUE if 'c' is a keyword character: Letters and characters from
  724.  * 'iskeyword' option for current buffer.
  725.  * For multi-byte characters mb_get_class() is used (builtin rules).
  726.  */
  727.     int
  728. vim_iswordc(c)
  729.     int c;
  730. {
  731. #ifdef FEAT_MBYTE
  732.     if (c >= 0x100)
  733.     {
  734.     if (enc_dbcs != 0)
  735.         return dbcs_class((unsigned)c >> 8, c & 0xff) >= 2;
  736.     if (enc_utf8)
  737.         return utf_class(c) >= 2;
  738.     }
  739. #endif
  740.     return (c > 0 && c < 0x100 && GET_CHARTAB(curbuf, c) != 0);
  741. }
  742.  
  743. /*
  744.  * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
  745.  */
  746.     int
  747. vim_iswordp(p)
  748.     char_u *p;
  749. {
  750. #ifdef FEAT_MBYTE
  751.     if (has_mbyte && MB_BYTE2LEN(*p) > 1)
  752.     return mb_get_class(p) >= 2;
  753. #endif
  754.     return GET_CHARTAB(curbuf, *p) != 0;
  755. }
  756.  
  757. #if defined(FEAT_SYN_HL) || defined(PROTO)
  758.     int
  759. vim_iswordc_buf(p, buf)
  760.     char_u    *p;
  761.     buf_T    *buf;
  762. {
  763. # ifdef FEAT_MBYTE
  764.     if (has_mbyte && MB_BYTE2LEN(*p) > 1)
  765.     return mb_get_class(p) >= 2;
  766. # endif
  767.     return (GET_CHARTAB(buf, *p) != 0);
  768. }
  769. #endif
  770.  
  771. /*
  772.  * return TRUE if 'c' is a valid file-name character
  773.  * Assume characters above 0x100 are valid (multi-byte).
  774.  */
  775.     int
  776. vim_isfilec(c)
  777.     int    c;
  778. {
  779.     return (c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR)));
  780. }
  781.  
  782. /*
  783.  * return TRUE if 'c' is a printable character
  784.  * Assume characters above 0x100 are printable (multi-byte), except for
  785.  * Unicode.
  786.  */
  787.     int
  788. vim_isprintc(c)
  789.     int c;
  790. {
  791. #ifdef FEAT_MBYTE
  792.     if (enc_utf8 && c >= 0x100)
  793.     return utf_printable(c);
  794. #endif
  795.     return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
  796. }
  797.  
  798. /*
  799.  * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
  800.  * byte of a double-byte character.
  801.  */
  802.     int
  803. vim_isprintc_strict(c)
  804.     int    c;
  805. {
  806. #ifdef FEAT_MBYTE
  807.     if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
  808.     return FALSE;
  809.     if (enc_utf8 && c >= 0x100)
  810.     return utf_printable(c);
  811. #endif
  812.     return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR)));
  813. }
  814.  
  815. /*
  816.  * like chartabsize(), but also check for line breaks on the screen
  817.  */
  818.     int
  819. lbr_chartabsize(s, col)
  820.     unsigned char    *s;
  821.     colnr_T        col;
  822. {
  823. #ifdef FEAT_LINEBREAK
  824.     if (!curwin->w_p_lbr && *p_sbr == NUL)
  825.     {
  826. #endif
  827. #ifdef FEAT_MBYTE
  828.     if (curwin->w_p_wrap)
  829.         return win_nolbr_chartabsize(curwin, s, col, NULL);
  830. #endif
  831.     RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
  832. #ifdef FEAT_LINEBREAK
  833.     }
  834.     return win_lbr_chartabsize(curwin, s, col, NULL);
  835. #endif
  836. }
  837.  
  838. /*
  839.  * Call lbr_chartabsize() and advance the pointer.
  840.  */
  841.     int
  842. lbr_chartabsize_adv(s, col)
  843.     char_u    **s;
  844.     colnr_T    col;
  845. {
  846.     int        retval;
  847.  
  848.     retval = lbr_chartabsize(*s, col);
  849. #ifdef FEAT_MBYTE
  850.     if (has_mbyte)
  851.     *s += (*mb_ptr2len_check)(*s);
  852.     else
  853. #endif
  854.     ++*s;
  855.     return retval;
  856. }
  857.  
  858. /*
  859.  * This function is used very often, keep it fast!!!!
  860.  *
  861.  * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
  862.  * string at start of line.  Warning: *headp is only set if it's a non-zero
  863.  * value, init to 0 before calling.
  864.  */
  865. /*ARGSUSED*/
  866.     int
  867. win_lbr_chartabsize(wp, s, col, headp)
  868.     win_T    *wp;
  869.     char_u    *s;
  870.     colnr_T    col;
  871.     int        *headp;
  872. {
  873. #ifdef FEAT_LINEBREAK
  874.     int        c;
  875.     int        size;
  876.     colnr_T    col2;
  877.     colnr_T    colmax;
  878.     int        added;
  879.     int        numberextra;
  880.     char_u    *ps;
  881.     int        tab_corr = (*s == TAB);
  882.  
  883.     /*
  884.      * No 'linebreak' and 'showbreak': return quickly.
  885.      */
  886.     if (!wp->w_p_lbr && *p_sbr == NUL)
  887. #endif
  888.     {
  889. #ifdef FEAT_MBYTE
  890.     if (wp->w_p_wrap)
  891.         return win_nolbr_chartabsize(wp, s, col, headp);
  892. #endif
  893.     RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
  894.     }
  895.  
  896. #ifdef FEAT_LINEBREAK
  897.     /*
  898.      * First get normal size, without 'linebreak'
  899.      */
  900.     size = win_chartabsize(wp, s, col);
  901.     c = *s;
  902.  
  903.     /*
  904.      * If 'linebreak' set check at a blank before a non-blank if the line
  905.      * needs a break here
  906.      */
  907.     if (wp->w_p_lbr
  908.         && vim_isbreak(c)
  909.         && !vim_isbreak(s[1])
  910.         && !wp->w_p_list
  911.         && wp->w_p_wrap
  912. # ifdef FEAT_VERTSPLIT
  913.         && wp->w_width != 0
  914. # endif
  915.        )
  916.     {
  917.     /*
  918.      * Count all characters from first non-blank after a blank up to next
  919.      * non-blank after a blank.
  920.      */
  921.     numberextra = win_col_off(wp);
  922.     col2 = col;
  923.     colmax = W_WIDTH(wp) - numberextra;
  924.     if (col >= colmax)
  925.         colmax += (((col - colmax)
  926.             / (colmax + win_col_off2(wp))) + 1)
  927.             * (colmax + win_col_off2(wp));
  928.     for (;;)
  929.     {
  930.         ps = s;
  931. # ifdef FEAT_MBYTE
  932.         if (has_mbyte)
  933.         s += (*mb_ptr2len_check)(s);
  934.         else
  935. # endif
  936.         ++s;
  937.         c = *s;
  938.         if (!(c != NUL
  939.             && (vim_isbreak(c)
  940.             || (!vim_isbreak(c)
  941.                 && (col2 == col || !vim_isbreak(*ps))))))
  942.         break;
  943.  
  944.         col2 += win_chartabsize(wp, s, col2);
  945.         if (col2 >= colmax)        /* doesn't fit */
  946.         {
  947.         size = colmax - col;
  948.         tab_corr = FALSE;
  949.         break;
  950.         }
  951.     }
  952.     }
  953.  
  954.     /*
  955.      * May have to add something for 'showbreak' string at start of line
  956.      * Set *headp to the size of what we add.
  957.      */
  958.     added = 0;
  959.     if (*p_sbr != NUL && wp->w_p_wrap && col != 0)
  960.     {
  961.     numberextra = win_col_off(wp);
  962.     col += numberextra;
  963.     if (col >= (colnr_T)W_WIDTH(wp))
  964.     {
  965.         col -= W_WIDTH(wp);
  966.         numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
  967.         if (numberextra > 0)
  968.         col = col % numberextra;
  969.     }
  970.     if (col == 0 || col + size > (colnr_T)W_WIDTH(wp))
  971.     {
  972.         added = (int)STRLEN(p_sbr);
  973.         if (tab_corr)
  974.         size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
  975.         else
  976.         size += added;
  977.         if (col != 0)
  978.         added = 0;
  979.     }
  980.     }
  981.     if (headp != NULL)
  982.     *headp = added;
  983.     return size;
  984. #endif
  985. }
  986.  
  987. #if defined(FEAT_MBYTE) || defined(PROTO)
  988. /*
  989.  * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
  990.  * 'wrap' is on.  This means we need to check for a double-byte character that
  991.  * doesn't fit at the end of the screen line.
  992.  */
  993.     static int
  994. win_nolbr_chartabsize(wp, s, col, headp)
  995.     win_T    *wp;
  996.     char_u    *s;
  997.     colnr_T    col;
  998.     int        *headp;
  999. {
  1000.     int        n;
  1001.  
  1002.     if (*s == TAB && (!wp->w_p_list || lcs_tab1))
  1003.     {
  1004.     n = wp->w_buffer->b_p_ts;
  1005.     return (int)(n - (col % n));
  1006.     }
  1007.     n = ptr2cells(s);
  1008.     /* Add one cell for a double-width character in the last column of the
  1009.      * window, displayed with a ">". */
  1010.     if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col))
  1011.     {
  1012.     if (headp != NULL)
  1013.         *headp = 1;
  1014.     return 3;
  1015.     }
  1016.     return n;
  1017. }
  1018.  
  1019. /*
  1020.  * Return TRUE if virtual column "vcol" is in the rightmost column of window
  1021.  * "wp".
  1022.  */
  1023.     int
  1024. in_win_border(wp, vcol)
  1025.     win_T    *wp;
  1026.     colnr_T    vcol;
  1027. {
  1028.     colnr_T    width1;        /* width of first line (after line number) */
  1029.     colnr_T    width2;        /* width of further lines */
  1030.  
  1031. #ifdef FEAT_VERTSPLIT
  1032.     if (wp->w_width == 0)    /* there is no border */
  1033.     return FALSE;
  1034. #endif
  1035.     width1 = W_WIDTH(wp) - win_col_off(wp);
  1036.     if (vcol < width1 - 1)
  1037.     return FALSE;
  1038.     if (vcol == width1 - 1)
  1039.     return TRUE;
  1040.     width2 = width1 + win_col_off2(wp);
  1041.     return ((vcol - width1) % width2 == width2 - 1);
  1042. }
  1043. #endif /* FEAT_MBYTE */
  1044.  
  1045. /*
  1046.  * Get virtual column number of pos.
  1047.  *  start: on the first position of this character (TAB, ctrl)
  1048.  * cursor: where the cursor is on this character (first char, except for TAB)
  1049.  *    end: on the last position of this character (TAB, ctrl)
  1050.  *
  1051.  * This is used very often, keep it fast!
  1052.  */
  1053.     void
  1054. getvcol(wp, pos, start, cursor, end)
  1055.     win_T    *wp;
  1056.     pos_T    *pos;
  1057.     colnr_T    *start;
  1058.     colnr_T    *cursor;
  1059.     colnr_T    *end;
  1060. {
  1061.     colnr_T    vcol;
  1062.     char_u    *ptr;        /* points to current char */
  1063.     char_u    *posptr;    /* points to char at pos->col */
  1064.     int        incr;
  1065.     int        head;
  1066.     int        ts = wp->w_buffer->b_p_ts;
  1067.     int        c;
  1068.  
  1069.     vcol = 0;
  1070.     ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
  1071.     posptr = ptr + pos->col;
  1072.  
  1073.     /*
  1074.      * This function is used very often, do some speed optimizations.
  1075.      * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
  1076.      * Also use this when 'list' is set but tabs take their normal size.
  1077.      */
  1078.     if ((!wp->w_p_list || lcs_tab1 != NUL)
  1079. #ifdef FEAT_LINEBREAK
  1080.         && !wp->w_p_lbr && *p_sbr == NUL
  1081. #endif
  1082.        )
  1083.     {
  1084. #ifndef FEAT_MBYTE
  1085.     head = 0;
  1086. #endif
  1087.     for (;;)
  1088.     {
  1089. #ifdef FEAT_MBYTE
  1090.         head = 0;
  1091. #endif
  1092.         c = *ptr;
  1093.         /* make sure we don't go past the end of the line */
  1094.         if (c == NUL)
  1095.         {
  1096.         incr = 1;    /* NUL at end of line only takes one column */
  1097.         break;
  1098.         }
  1099.         /* A tab gets expanded, depending on the current column */
  1100.         if (c == TAB)
  1101.         incr = ts - (vcol % ts);
  1102.         else
  1103.         {
  1104. #ifdef FEAT_MBYTE
  1105.         if (has_mbyte)
  1106.         {
  1107.             /* For utf-8, if the byte is >= 0x80, need to look at
  1108.              * further bytes to find the cell width. */
  1109.             if (enc_utf8 && c >= 0x80)
  1110.             incr = utf_ptr2cells(ptr);
  1111.             else
  1112.             incr = CHARSIZE(c);
  1113.  
  1114.             /* If a double-cell char doesn't fit at the end of a line
  1115.              * it wraps to the next line, it's like this char is three
  1116.              * cells wide. */
  1117.             if (incr == 2 && wp->w_p_wrap && in_win_border(wp, vcol))
  1118.             {
  1119.             ++incr;
  1120.             head = 1;
  1121.             }
  1122.         }
  1123.         else
  1124. #endif
  1125.             incr = CHARSIZE(c);
  1126.         }
  1127.  
  1128.         if (ptr >= posptr)    /* character at pos->col */
  1129.         break;
  1130.  
  1131.         vcol += incr;
  1132. #ifdef FEAT_MBYTE
  1133.         if (has_mbyte)
  1134.         ptr += (*mb_ptr2len_check)(ptr);
  1135.         else
  1136. #endif
  1137.         ++ptr;
  1138.     }
  1139.     }
  1140.     else
  1141.     {
  1142.     for (;;)
  1143.     {
  1144.         /* A tab gets expanded, depending on the current column */
  1145.         head = 0;
  1146.         incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
  1147.         /* make sure we don't go past the end of the line */
  1148.         if (*ptr == NUL)
  1149.         {
  1150.         incr = 1;    /* NUL at end of line only takes one column */
  1151.         break;
  1152.         }
  1153.  
  1154.         if (ptr >= posptr)    /* character at pos->col */
  1155.         break;
  1156.  
  1157.         vcol += incr;
  1158. #ifdef FEAT_MBYTE
  1159.         if (has_mbyte)
  1160.         ptr += (*mb_ptr2len_check)(ptr);
  1161.         else
  1162. #endif
  1163.         ++ptr;
  1164.     }
  1165.     }
  1166.     if (start != NULL)
  1167.     *start = vcol + head;
  1168.     if (end != NULL)
  1169.     *end = vcol + incr - 1;
  1170.     if (cursor != NULL)
  1171.     {
  1172.     if (*ptr == TAB
  1173.         && (State & NORMAL)
  1174.         && !wp->w_p_list
  1175.         && !virtual_active()
  1176. #ifdef FEAT_VISUAL
  1177.         && !(VIsual_active && *p_sel == 'e')
  1178. #endif
  1179.         )
  1180.         *cursor = vcol + incr - 1;        /* cursor at end */
  1181.     else
  1182.         *cursor = vcol + head;        /* cursor at start */
  1183.     }
  1184. }
  1185.  
  1186. /*
  1187.  * Get virtual cursor column in the current window, pretending 'list' is off.
  1188.  */
  1189.     colnr_T
  1190. getvcol_nolist(posp)
  1191.     pos_T    *posp;
  1192. {
  1193.     int        list_save = curwin->w_p_list;
  1194.     colnr_T    vcol;
  1195.  
  1196.     curwin->w_p_list = FALSE;
  1197.     getvcol(curwin, posp, NULL, &vcol, NULL);
  1198.     curwin->w_p_list = list_save;
  1199.     return vcol;
  1200. }
  1201.  
  1202. #if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
  1203. /*
  1204.  * Get virtual column in virtual mode.
  1205.  */
  1206.     void
  1207. getvvcol(wp, pos, start, cursor, end)
  1208.     win_T    *wp;
  1209.     pos_T    *pos;
  1210.     colnr_T    *start;
  1211.     colnr_T    *cursor;
  1212.     colnr_T    *end;
  1213. {
  1214.     colnr_T    col;
  1215.     char_u    *ptr;
  1216.  
  1217.     if (virtual_active())
  1218.     {
  1219.     /* For virtual mode, only want one value */
  1220.     getvcol(wp, pos, &col, NULL, NULL);
  1221.  
  1222.     if (pos->coladd > 0)
  1223.     {
  1224.         /* Adjust for multiwide char */
  1225.         ptr = ml_get(pos->lnum);
  1226.         if (pos->col <= STRLEN(ptr))
  1227.         {
  1228.         ptr += pos->col;
  1229.         if (*ptr != TAB && *ptr != NUL && ptr2cells(ptr) > 1)
  1230.             pos->coladd = 0;
  1231.         }
  1232.         col += pos->coladd;
  1233.     }
  1234.     if (start != NULL)
  1235.         *start = col;
  1236.     if (cursor != NULL)
  1237.         *cursor = col;
  1238.     if (end != NULL)
  1239.         *end = col;
  1240.     }
  1241.     else
  1242.     getvcol(wp, pos, start, cursor, end);
  1243. }
  1244. #endif
  1245.  
  1246. #if defined(FEAT_VISUAL) || defined(PROTO)
  1247. /*
  1248.  * Get the leftmost and rightmost virtual column of pos1 and pos2.
  1249.  * Used for Visual block mode.
  1250.  */
  1251.     void
  1252. getvcols(wp, pos1, pos2, left, right)
  1253.     win_T    *wp;
  1254.     pos_T    *pos1, *pos2;
  1255.     colnr_T    *left, *right;
  1256. {
  1257.     colnr_T    from1, from2, to1, to2;
  1258.  
  1259.     if (ltp(pos1, pos2))
  1260.     {
  1261.     getvvcol(wp, pos1, &from1, NULL, &to1);
  1262.     getvvcol(wp, pos2, &from2, NULL, &to2);
  1263.     }
  1264.     else
  1265.     {
  1266.     getvvcol(wp, pos2, &from1, NULL, &to1);
  1267.     getvvcol(wp, pos1, &from2, NULL, &to2);
  1268.     }
  1269.     if (from2 < from1)
  1270.     *left = from2;
  1271.     else
  1272.     *left = from1;
  1273.     if (to2 > to1)
  1274.     {
  1275.     if (*p_sel == 'e' && from2 - 1 >= to1)
  1276.         *right = from2 - 1;
  1277.     else
  1278.         *right = to2;
  1279.     }
  1280.     else
  1281.     *right = to1;
  1282. }
  1283. #endif
  1284.  
  1285. /*
  1286.  * skipwhite: skip over ' ' and '\t'.
  1287.  */
  1288.     char_u *
  1289. skipwhite(p)
  1290.     char_u    *p;
  1291. {
  1292.     while (vim_iswhite(*p)) /* skip to next non-white */
  1293.     ++p;
  1294.     return p;
  1295. }
  1296.  
  1297. /*
  1298.  * skipdigits: skip over digits;
  1299.  */
  1300.     char_u *
  1301. skipdigits(p)
  1302.     char_u    *p;
  1303. {
  1304.     while (isdigit(*p))    /* skip to next non-digit */
  1305.     ++p;
  1306.     return p;
  1307. }
  1308.  
  1309. /*
  1310.  * vim_isdigit: version of isdigit() that can handle characters > 0x100.
  1311.  */
  1312.     int
  1313. vim_isdigit(c)
  1314.     int        c;
  1315. {
  1316.     return (c > 0 && c < 0x100 && isdigit(c));
  1317. }
  1318.  
  1319. /*
  1320.  * skiptowhite: skip over text until ' ' or '\t' or NUL.
  1321.  */
  1322.     char_u *
  1323. skiptowhite(p)
  1324.     char_u    *p;
  1325. {
  1326.     while (*p != ' ' && *p != '\t' && *p != NUL)
  1327.     ++p;
  1328.     return p;
  1329. }
  1330.  
  1331. #if defined(FEAT_LISTCMDS) || defined(PROTO)
  1332. /*
  1333.  * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
  1334.  */
  1335.     char_u *
  1336. skiptowhite_esc(p)
  1337.     char_u    *p;
  1338. {
  1339.     while (*p != ' ' && *p != '\t' && *p != NUL)
  1340.     {
  1341.     if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
  1342.         ++p;
  1343.     ++p;
  1344.     }
  1345.     return p;
  1346. }
  1347. #endif
  1348.  
  1349. /*
  1350.  * Getdigits: Get a number from a string and skip over it.
  1351.  * Note: the argument is a pointer to a char_u pointer!
  1352.  */
  1353.     long
  1354. getdigits(pp)
  1355.     char_u **pp;
  1356. {
  1357.     char_u    *p;
  1358.     long    retval;
  1359.  
  1360.     p = *pp;
  1361.     retval = atol((char *)p);
  1362.     if (*p == '-')        /* skip negative sign */
  1363.     ++p;
  1364.     p = skipdigits(p);        /* skip to next non-digit */
  1365.     *pp = p;
  1366.     return retval;
  1367. }
  1368.  
  1369. /*
  1370.  * Return TRUE if "lbuf" is empty or only contains blanks.
  1371.  */
  1372.     int
  1373. vim_isblankline(lbuf)
  1374.     char_u    *lbuf;
  1375. {
  1376.     char_u    *p;
  1377.  
  1378.     p = skipwhite(lbuf);
  1379.     return (*p == NUL || *p == '\r' || *p == '\n');
  1380. }
  1381.  
  1382. /*
  1383.  * Convert a string into a long and/or unsigned long, taking care of
  1384.  * hexadecimal and octal numbers.
  1385.  * If "hexp" is not NULL, returns a flag to indicate the type of the number:
  1386.  *  0        decimal
  1387.  *  '0'        octal
  1388.  *  'X'        hex
  1389.  *  'x'        hex
  1390.  * If "len" is not NULL, the length of the number in characters is returned.
  1391.  * If "nptr" is not NULL, the signed result is returned in it.
  1392.  * If "unptr" is not NULL, the unsigned result is returned in it.
  1393.  */
  1394.     void
  1395. vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
  1396.     char_u        *start;
  1397.     int            *hexp;        /* return: type of number 0 = decimal, 'x'
  1398.                        or 'X' is hex, '0' = octal */
  1399.     int            *len;        /* return: detected length of number */
  1400.     int            dooct;        /* recognize octal number */
  1401.     int            dohex;        /* recognize hex number */
  1402.     long        *nptr;        /* return: signed result */
  1403.     unsigned long    *unptr;        /* return: unsigned result */
  1404. {
  1405.     char_u        *ptr = start;
  1406.     int            hex = 0;        /* default is decimal */
  1407.     int            negative = FALSE;
  1408.     long        n = 0;
  1409.     unsigned long   un = 0;
  1410.  
  1411.     if (ptr[0] == '-')
  1412.     {
  1413.     negative = TRUE;
  1414.     ++ptr;
  1415.     }
  1416.  
  1417.     if (ptr[0] == '0')            /* could be hex or octal */
  1418.     {
  1419.     hex = ptr[1];
  1420.     if (dohex && (hex == 'X' || hex == 'x') && isxdigit(ptr[2]))
  1421.         ptr += 2;            /* hexadecimal */
  1422.     else
  1423.     {
  1424.         if (dooct && isdigit(hex))
  1425.         hex = '0';        /* octal */
  1426.         else
  1427.         hex = 0;        /* 0 by itself is decimal */
  1428.     }
  1429.     }
  1430.  
  1431.     /*
  1432.      * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
  1433.      */
  1434.     if (hex)
  1435.     {
  1436.     if (hex == '0')
  1437.     {
  1438.         /* octal */
  1439.         while ('0' <= *ptr && *ptr <= '7')
  1440.         {
  1441.         n = 8 * n + (long)(*ptr - '0');
  1442.         un = 8 * un + (unsigned long)(*ptr - '0');
  1443.         ++ptr;
  1444.         }
  1445.     }
  1446.     else
  1447.     {
  1448.         /* hex */
  1449.         while (isxdigit(*ptr))
  1450.         {
  1451.         n = 16 * n + (long)hex2nr(*ptr);
  1452.         un = 16 * un + (unsigned long)hex2nr(*ptr);
  1453.         ++ptr;
  1454.         }
  1455.     }
  1456.     }
  1457.     else
  1458.     {
  1459.     /* decimal */
  1460.     while (isdigit(*ptr))
  1461.     {
  1462.         n = 10 * n + (long)(*ptr - '0');
  1463.         un = 10 * un + (unsigned long)(*ptr - '0');
  1464.         ++ptr;
  1465.     }
  1466.     }
  1467.  
  1468.     if (!hex && negative)   /* account for leading '-' for decimal numbers */
  1469.     n = -n;
  1470.  
  1471.     if (hexp != NULL)
  1472.     *hexp = hex;
  1473.     if (len != NULL)
  1474.     *len = (int)(ptr - start);
  1475.     if (nptr != NULL)
  1476.     *nptr = n;
  1477.     if (unptr != NULL)
  1478.     *unptr = un;
  1479. }
  1480.  
  1481. /*
  1482.  * Return the value of a single hex character.
  1483.  * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
  1484.  */
  1485.     int
  1486. hex2nr(c)
  1487.     int        c;
  1488. {
  1489.     if (c >= 'a' && c <= 'f')
  1490.     return c - 'a' + 10;
  1491.     if (c >= 'A' && c <= 'F')
  1492.     return c - 'A' + 10;
  1493.     return c - '0';
  1494. }
  1495.  
  1496. #if defined(FEAT_TERMRESPONSE) || defined(PROTO)
  1497. /*
  1498.  * Convert two hex characters to a byte.
  1499.  * Return -1 if one of the characters is not hex.
  1500.  */
  1501.     int
  1502. hexhex2nr(p)
  1503.     char_u    *p;
  1504. {
  1505.     if (!isxdigit(p[0]) || !isxdigit(p[1]))
  1506.     return -1;
  1507.     return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
  1508. }
  1509. #endif
  1510.  
  1511. /*
  1512.  * Return TRUE if "str" starts with a backslash that should be removed.
  1513.  * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
  1514.  * backslash is not a normal file name character.
  1515.  * '$' is a valid file name character, we don't remove the backslash before
  1516.  * it.  This means it is not possible to use an environment variable after a
  1517.  * backslash.  "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
  1518.  * Although "\ name" is valid, the backslash in "Program\ files" must be
  1519.  * removed.  Assume a file name doesn't start with a space.
  1520.  * For multi-byte names, never remove a backslash before a non-ascii
  1521.  * character, assume that all multi-byte characters are valid file name
  1522.  * characters.
  1523.  */
  1524.     int
  1525. rem_backslash(str)
  1526.     char_u  *str;
  1527. {
  1528. #ifdef BACKSLASH_IN_FILENAME
  1529.     return (str[0] == '\\'
  1530. # ifdef FEAT_MBYTE
  1531.         && str[1] < 0x80
  1532. # endif
  1533.         && (str[1] == ' '
  1534.         || (str[1] != NUL
  1535.             && str[1] != '*'
  1536.             && str[1] != '?'
  1537.             && !vim_isfilec(str[1]))));
  1538. #else
  1539.     return (str[0] == '\\' && str[1] != NUL);
  1540. #endif
  1541. }
  1542.  
  1543. /*
  1544.  * Halve the number of backslashes in a file name argument.
  1545.  * For MS-DOS we only do this if the character after the backslash
  1546.  * is not a normal file character.
  1547.  */
  1548.     void
  1549. backslash_halve(p)
  1550.     char_u    *p;
  1551. {
  1552.     for ( ; *p; ++p)
  1553.     if (rem_backslash(p))
  1554.         STRCPY(p, p + 1);
  1555. }
  1556.  
  1557. /*
  1558.  * backslash_halve() plus save the result in allocated memory.
  1559.  */
  1560.     char_u *
  1561. backslash_halve_save(p)
  1562.     char_u    *p;
  1563. {
  1564.     char_u    *res;
  1565.  
  1566.     res = vim_strsave(p);
  1567.     if (res == NULL)
  1568.     return p;
  1569.     backslash_halve(res);
  1570.     return res;
  1571. }
  1572.  
  1573. #if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO)
  1574. /*
  1575.  * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c!
  1576.  * The first 64 entries have been added to map control characters defined in
  1577.  * ascii.h
  1578.  */
  1579. static char_u ebcdic2ascii_tab[256] =
  1580. {
  1581.     0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177,
  1582.     0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
  1583.     0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027,
  1584.     0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037,
  1585.     0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
  1586.     0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
  1587.     0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
  1588.     0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
  1589.     0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
  1590.     0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
  1591.     0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
  1592.     0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
  1593.     0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
  1594.     0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
  1595.     0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
  1596.     0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
  1597.     0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
  1598.     0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
  1599.     0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
  1600.     0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
  1601.     0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
  1602.     0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
  1603.     0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
  1604.     0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
  1605.     0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
  1606.     0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
  1607.     0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
  1608.     0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
  1609.     0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
  1610.     0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
  1611.     0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
  1612.     0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377
  1613. };
  1614.  
  1615. /*
  1616.  * Convert a buffer worth of characters from EBCDIC to ASCII.  Only useful if
  1617.  * wanting 7-bit ASCII characters out the other end.
  1618.  */
  1619.     void
  1620. ebcdic2ascii(buffer, len)
  1621.     char_u    *buffer;
  1622.     int        len;
  1623. {
  1624.     int        i;
  1625.  
  1626.     for (i = 0; i < len; i++)
  1627.     buffer[i] = ebcdic2ascii_tab[buffer[i]];
  1628. }
  1629. #endif
  1630.